/**
 * 语义化
 * async 表示函数里有异步操作
 * await 表示紧跟在后面的表达式需要等待结果
 */
async function func() {
    // await 命令后面，可以是 Promise 对象，也可以是原始类型的值（数值，字符串，布尔值，这时会自动转成立即 resolved 的 Promise 对象）
    console.log(await 456)
    // async 函数内部一旦遇到 await 命令后的 Promise 对象是 rejected 状态的或者是抛出错误，会直接终止运行
    console.log(await Promise.reject(new Error('func error')))
    console.log(await 789)
    // async 函数内部 return 语句返回的值，会成为 then 方法回调函数的参数
    return 123
}

// async 函数的返回值是 Promise 对象，可以用 then 方法指定下一步操作
console.log(func())

/**
 * 总结：async 函数可以看作多个异步操作，包装成的一个 Promise 对象，而 await 命令就是内部 then 命令的语法糖
 */

async function functhrow() {
    // async 函数内部抛出错误，会导致返回的 Promise 对象变为 rejected 状态，抛出的错误可以被 catch 方法回调函数抓到作为参数
    throw new Error('error')
}

console.log(functhrow())

functhrow().catch(err => {
    console.log(err)
})

async function funcreturn() {
    // async 函数返回的 Promise 对象，必须等到内部所有 await 命令后面的 Promise 对象状态改变后，才会发生状态改变
    // 除非遇到 return 语句或者抛出错误
    return
}

console.log(funcreturn())

async function funcfinal1() {
    try {
        await Promise.reject('出错了1')
    } catch (err) {
        console.log(err)
        return err
    }
}

console.log(funcfinal1())

async function funcfinal2() {
    console.log(
        await Promise.reject('出错了2').catch(err => {
            console.log(err)
            return err
        })
    )
}

console.log(funcfinal2())
